# ws_client.py
import asyncio
import json
import websockets
from typing import Optional
from nonebot import get_bot, logger, require, get_plugin_config
from nonebot.plugin import PluginMetadata, inherit_supported_adapters
from pydantic import BaseModel, Field

require("nonebot_plugin_apscheduler")
from nonebot_plugin_apscheduler import scheduler


class Config(BaseModel):
    ws_server_url: str = Field("ws://localhost:8765", description="ws服务器地址")
    target_group: int = Field(259248174, description="目标QQ群号")

__plugin_meta__ = PluginMetadata(
    name="nonebot_plugin_qwq_mclistener_ws_client",
    description="通过WebSocket接收Minecraft服务器事件并通知到QQ群",
    usage="通过WebSocket接收Minecraft服务器事件并通知到QQ群",
    config=Config,
    supported_adapters=inherit_supported_adapters("nonebot_plugin_apscheduler"),
)

class WSClient:
    def __init__(self):
        self.ws: Optional[websockets.WebSocketException] = None
        self.connected = False
        self.config = get_plugin_config(Config)
        self.lock = asyncio.Lock()
        
    async def connect(self):
        async with self.lock:
            if self.connected:
                return
        while True:
            try:
                self.ws = await websockets.connect(
                    self.config.ws_server_url,
                    ping_interval=30,
                    ping_timeout=5
                )
                self.connected = True
                logger.success(f"成功连接到WebSocket服务器: {self.config.ws_server_url}")
                await self.listen()
            except Exception as e:
                logger.error(f"WebSocket 连接失败: {str(e)}, 5s后重试...")
                self.connected = False
                await asyncio.sleep(5)
    async def listen(self):
        try:
            async for message in self.ws:
                await self.handle_message(message)
        except websockets.ConnectionClosed:
            logger.warning("WebSocket 连接已关闭, 尝试重连...")
            self.connected = False
            await self.connect()
            
    async def handle_message(self, message: str):
        try:
            data = json.loads(message)
            msg_type = data.get("type")
            player = data.get("player_name")
            
            if msg_type == "player_join":
                content = f"玩家 {player} 加入了服务器！"
            elif msg_type == "player_leave":
                content = f"玩家 {player} 离开了服务器！"
            else:
                return
            
            await self.send_group_message(content)
        
        except Exception as e:
            logger.error(f"处理消息失败: {str(e)}")
    
    async def send_group_message(self, content: str):
        bot = get_bot()
        try:
            await bot.send_group_msg(
                group_id=self.config.target_group,
                message=content
            )
        except Exception as e:
            logger.error(f"向 QQ 群 {self.config.target_group} 发送消息失败: {str(e)}")
            
client = WSClient()

@scheduler.scheduled_job(
    "interval", 
    seconds=5,
    id="ws_connect",
    max_instances=2,
    coalesce=True,
)

async def keep_connection():
    if not client.connected:
        await client.connect()
        
async def shutdown():
    if client.ws and not client.ws.closed:
        await client.ws.close()